package model

import (
	"Short_chain_cats/database"
	"context"
	"time"
)

const DEFAULT_AVATAR = "http://sems1.oss-cn-beijing.aliyuncs.com/20240625/avatar6.jpg"

var UserModel = User{}

// User 定义了用户模型，对应数据库中的 user 表
type User struct {
	Id           int    `gorm:"column:id" json:"id"`
	UserAccount  string `gorm:"column:userAccount;not null" json:"userAccount"`   // 账号
	UserPassword string `gorm:"column:userPassword;not null" json:"userPassword"` // 密码
	UserEmail    string `gorm:"column:userEmail" json:"userEmail"`                //用户邮箱
	//UnionId      string    `gorm:"column:unionId" json:"unionId"`                                 // 微信开放平台id
	//MpOpenId     string    `gorm:"column:mpOpenId" json:"mpOpenId"`                               // 公众号openId
	//UserName     string    `gorm:"column:userName" json:"userName"`                               // 用户昵称
	UserAvatar  string    `gorm:"column:userAvatar" json:"userAvatar"`                           // 用户头像
	UserProfile string    `gorm:"column:userProfile" json:"userProfile"`                         // 用户简介
	UserRole    string    `gorm:"column:userRole;default:user;not null" json:"userRole"`         // 用户角色：user/admin/ban
	CreateTime  time.Time `gorm:"column:createTime;default:CURRENT_TIMESTAMP" json:"createTime"` // 创建时间
	UpdateTime  time.Time `gorm:"column:updateTime;default:CURRENT_TIMESTAMP" json:"updateTime"` // 更新时间
	IsDelete    int8      `gorm:"column:isDelete;default:0;not null" json:"isDelete"`            // 是否删除
	AToken      string    `gorm:"-" json:"aToken"`
}

// TableName 指定 User 模型对应的数据库表名
func (User) TableName() string {
	return "user"
}

// DailyCount 数据模型来保存历史注册人数
type DailyCount struct {
	Date  string `json:"date"` // 日期格式应为 YYYY-MM-DD
	Count int64  `json:"count"`
}

type CreateUserCommand struct {
	UserAccount   string `form:"userAccount" json:"userAccount" binding:"required,min=2,max=100"`
	UserPassword  string `form:"userPassword" json:"userPassword" binding:"required,min=8,max=16"`
	CheckPassword string `form:"checkPassword" json:"checkPassword" binding:"required,min=8,max=16,eqfield=UserPassword"`
	UserEmail     string `form:"userEmail" json:"userEmail" binding:"required,email"` // 用户邮箱，必须是有效的邮箱格式
	EmailCode     string `form:"emailCode" json:"emailCode" binding:"required"`
}

type UserLoginCommand struct {
	UserAccount  string `form:"userAccount" json:"userAccount" binding:"required,min=2,max=100"`
	UserPassword string `form:"userPassword" json:"userPassword" binding:"required,min=8,max=16"`
}
type RefreshTokenCommand struct {
	UserAccount string `form:"userAccount" json:"userAccount" binding:"required,min=2,max=100"`
}

type EmailCommand struct {
	UserEmail string `form:"userEmail" json:"userEmail" binding:"required,email"` // 用户邮箱，必须是有效的邮箱格式
}

type UpdateUserCommand struct {
	UserAccount string `form:"userAccount" json:"userAccount" binding:"required,min=2,max=100"` // 用户账号，长度在 2 到 100 之间
	UserProfile string `form:"userProfile" json:"userProfile" binding:"omitempty"`              // 用户简介，长度在 2 到 100 之间
}
type ForgetPasswordCommand struct {
	NewPassword   string `form:"newPassword" json:"newPassword" binding:"required,min=8,max=16"`
	CheckPassword string `form:"checkPassword" json:"checkPassword" binding:"required,min=8,max=16,eqfield=NewPassword"`
	UserEmail     string `form:"userEmail" json:"userEmail" binding:"required,email"` // 用户邮箱，必须是有效的邮箱格式
	EmailCode     string `form:"emailCode" json:"emailCode" binding:"required"`
}

type UpdateUserPasswordCommand struct {
	OldPassword string `form:"oldPassword" json:"oldPassword" binding:"required,min=8,max=16"`
	NewPassword string `form:"newPassword" json:"newPassword" binding:"required,min=8,max=16"`
}

type DateCommand struct {
	StartDate string `json:"startDate" binding:"omitempty,datetime=2006-01-02"`
	EndDate   string `json:"endDate" binding:"omitempty,datetime=2006-01-02"`
}

type GetALLCommand struct {
	//Id          int    `form:"id" json:"id" binding:"omitempty"`
	UserAccount string `form:"userAccount" json:"userAccount" binding:"omitempty"` // 用户账号，长度在 2 到 100 之间
	UserProfile string `form:"userProfile" json:"userProfile" binding:"omitempty"` // 用户简介，长度在 2 到 100 之间
	UserRole    string `form:"userRole" json:"userRole" binding:"omitempty"`
	Page        int    `form:"page" json:"page" binding:"omitempty"`
	PageSize    int    `form:"pageSize" json:"pageSize"  binding:"omitempty"`
	CreateOrder int    `form:"createOrder" json:"createOrder" binding:"omitempty"`
	UpdateOrder int    `form:"updateOrder" json:"updateOrder" binding:"omitempty"`
}

type EditUserCommand struct {
	Id          int    `form:"id" json:"id" binding:"required"`
	UserAccount string `form:"userAccount" json:"userAccount" binding:"required,min=2,max=100"` // 用户账号，长度在 2 到 100 之间
	UserProfile string `form:"userProfile" json:"userProfile" binding:"omitempty"`              // 用户简介，长度在 2 到 100 之间
	UserRole    string `form:"userRole" json:"userRole" binding:"omitempty"`
}
type IdCommand struct {
	Id []int `form:"id" json:"id" binding:"required"`
}
type ExportExcelCommand struct {
	User []*User `form:"user" json:"user" binding:"required"`
}

func (User) GetCountByAccount(ctx context.Context, account string) (int64, error) {
	var count int64
	err := database.NewOrm(ctx).Model(&UserModel).Where("isDelete=0 and userAccount = ?", account).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}
func (User) GetCountByEmail(ctx context.Context, email string) (int64, error) {
	var count int64
	err := database.NewOrm(ctx).Model(&UserModel).Where("isDelete=0 and userEmail = ?", email).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

func (User) GetUserByAccount(ctx context.Context, account string) (*User, error) {
	var user *User
	err := database.NewOrm(ctx).Model(&UserModel).Where("isDelete=0 and userAccount = ?", account).First(&user).Error
	if err != nil {
		return &User{}, err
	}
	return user, nil
}

func (User) GetById(ctx context.Context, id int) (*User, error) {
	var user User
	err := database.NewOrm(ctx).Where("isDelete=0 and id = ?", id).First(&user).Error
	if err != nil {
		return &User{}, err
	}
	return &user, nil
}

func (User) GetByEmail(ctx context.Context, email string) (*User, error) {
	var user User
	err := database.NewOrm(ctx).Where("isDelete=0 and userEmail = ?", email).First(&user).Error
	if err != nil {
		return &User{}, err
	}
	return &user, nil
}

func (User) Create(ctx context.Context, param *CreateUserCommand) (*User, error) {
	user := User{
		UserAvatar:   DEFAULT_AVATAR,
		UserAccount:  param.UserAccount,
		UserPassword: param.UserPassword,
		UserEmail:    param.UserEmail,
		CreateTime:   time.Now(),
		UpdateTime:   time.Now(),
	}
	err := database.NewOrm(ctx).Create(&user).Error
	if err != nil {
		return &User{}, err
	}
	return &user, nil
}

func (User) UpdateUserInfo(ctx context.Context, user *User) (*User, error) {
	err := database.NewOrm(ctx).Table("user").Where("id=?", user.Id).Updates(user).Error
	if err != nil {
		return &User{}, err
	}
	return user, nil
}

func (User) UpdateUser(ctx context.Context, id int, user map[string]interface{}) error {
	err := database.NewOrm(ctx).Table("user").Where("id=?", id).Updates(user).Error
	if err != nil {
		return err
	}
	return nil
}

func (User) GetUserCount(ctx context.Context) (int64, error) {
	var count int64
	err := database.NewOrm(ctx).Model(&UserModel).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

func (u User) GetShortChainCount(ctx context.Context) (int64, error) {
	var count int64
	err := database.NewOrm(ctx).Table("url_relate").Distinct("id").Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, nil
}

func (u User) SaveDailyRegisterCountsToDB(ctx context.Context, count DailyCount) error {
	return database.NewOrm(ctx).
		Table("daily_counts").
		Select("date", "count").
		Create(&map[string]interface{}{
			"date":  count.Date,
			"count": count.Count,
			"type":  1, // 假设 type 为 1 表示注册人数
		}).Error
}

func (u User) GetDailyRegisterCountsToDB(ctx context.Context, dates []string) ([]DailyCount, error) {
	var results []DailyCount
	err := database.NewOrm(ctx).Table("daily_counts").Where("type=1 and date IN (?)", dates).Order("date asc").Find(&results).Error
	if err != nil {
		return nil, err
	}
	return results, nil
}

func (u User) GetDailyShortChainCountsToDB(ctx context.Context, dates []string) ([]DailyCount, error) {
	var results []DailyCount
	err := database.NewOrm(ctx).Table("daily_counts").Where("type=2 and date IN (?)", dates).Order("date asc").Find(&results).Error
	if err != nil {
		return nil, err
	}
	return results, nil
}

func (u User) SaveDailyShortChainCountsToDB(ctx context.Context, count DailyCount) error {
	return database.NewOrm(ctx).
		Table("daily_counts").
		Select("date", "count").
		Create(&map[string]interface{}{
			"date":  count.Date,
			"count": count.Count,
			"type":  2, // 假设 type 为 2 表示短链生成数
		}).Error
}

func (u User) GetEmailById(ctx context.Context, id int) (string, error) {
	var email string
	err := database.NewOrm(ctx).Table("user").Where("isDelete=0 and id = ?", id).Select("userEmail").First(&email).Error
	if err != nil {
		return "", err
	}
	return email, nil
}

func (u User) UploadAvatarById(ctx context.Context, id int, url string) error {
	err := database.NewOrm(ctx).Table("user").Where("isDelete=0 and id = ?", id).Update("userAvatar", url).Error
	if err != nil {
		return err
	}
	return nil
}

func (u User) GetAll(ctx context.Context, userAccount, userProfile, userRole string, page, pageSize, createOrder, updateOrder int) ([]*User, int64, error) {
	var totalCount int64
	var users []*User
	session := database.NewOrm(ctx)
	// 构建查询条件
	cond := session.Model(&User{})
	cond = cond.Where("isDelete=0")
	// 构建查询条件
	if userAccount != "" {
		cond = cond.Where("userAccount like ?", "%"+userAccount+"%")
	}
	if userProfile != "" {
		cond = cond.Where("userProfile like ?", "%"+userProfile+"%")
	}
	if userRole != "" {
		cond = cond.Where("userRole = ?", userRole)
	}

	// 先获取总数，此时不应有 Limit 和 Offset
	if err := cond.Count(&totalCount).Error; err != nil {
		return nil, 0, err
	}
	// 添加分页
	cond = cond.Limit(pageSize).Offset((page - 1) * pageSize)

	//添加排序
	if createOrder == 1 {
		cond = cond.Order("createTime desc")
	} else if createOrder == 2 {
		cond = cond.Order("createTime asc")
	}
	if updateOrder == 1 {
		cond = cond.Order("updateTime desc")
	} else if updateOrder == 2 {
		cond = cond.Order("updateTime asc")
	}
	err := cond.Find(&users).Error
	if err != nil {
		return nil, 0, err
	}
	return users, totalCount, nil
}

func (u User) DeleteUsers(ctx context.Context, id []int) error {
	return database.NewOrm(ctx).Table("user").Where("id in (?)", id).Update("isDelete", 1).Error
}
